package edu.kufpg.armatus.util;
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import org.apache.commons.collections4.trie.PatriciaTrie;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.common.base.Optional;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.BoundType;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableRangeMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedMultiset;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.Ordering;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.TreeMultiset;
import com.google.common.collect.TreeRangeMap;
public class ParcelUtils {
private static final Class<?>[] COMPARATOR_ARG = new Class<?>[] { Comparator.class };
// private static final String TAG = ParcelUtils.class.getSimpleName();
private static final String CREATE = "create";
private static final String BUILDER = "builder";
private static final int VAL_BOOLEAN = 25;
private static final int VAL_ENUM = 26;
private static final int VAL_LIST2 = 27;
private static final int VAL_PATRICIATRIE = 28;
private static final int VAL_SORTEDMAP = 29;
private static final int VAL_MAP2 = 30;
private static final int VAL_TREEMULTIMAP = 31;
private static final int VAL_SORTEDSETMULTIMAP = 32;
private static final int VAL_MULTIMAP = 33;
private static final int VAL_SORTEDMULTISET = 34;
private static final int VAL_MULTISET = 35;
private static final int VAL_OPTIONAL = 36;
private static final int VAL_PRIORITYQUEUE = 37;
private static final int VAL_QUEUE = 38;
private static final int VAL_RANGE = 39;
private static final int VAL_RANGEMAP = 40;
private static final int VAL_SORTEDSET = 41;
private static final int VAL_SET = 42;
private static final int VAL_COLLECTION = 43;
private ParcelUtils() {}
public static boolean readBoolean(Parcel p) {
return p.readInt() != 0;
}
public static <E extends Enum<E>> E readEnum(Parcel p) {
String className = p.readString();
if (className == null) {
return null;
} else {
@SuppressWarnings("unchecked")
Class<E> cls = (Class<E>) ReflectionUtils.forName(className);
String valueName = p.readString();
return Enum.valueOf(cls, valueName);
}
}
public static <E> List<E> readList(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableList.class, name)) {
return readImmutableListInternal(p);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
List<E> outVal = (List<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
}
}
public static <E> ArrayList<E> readArrayList(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
ArrayList<E> outVal = new ArrayList<E>(n);
return addToCollection(p, outVal, n);
}
}
public static <E> LinkedList<E> readLinkedList(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
LinkedList<E> outVal = new LinkedList<E>();
return addToCollection(p, outVal, n);
}
}
public static <E> Stack<E> readStack(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Stack<E> outVal = new Stack<E>();
return addToCollection(p, outVal, n);
}
}
public static <E> Vector<E> readVector(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Vector<E> outVal = new Vector<E>(n);
return addToCollection(p, outVal, n);
}
}
public static <E> ImmutableList<E> readImmutableList(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableListInternal(p);
}
}
private static <E> ImmutableList<E> readImmutableListInternal(Parcel p) {
int n = p.readInt();
ImmutableList.Builder<E> builder = ImmutableList.builder();
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
public static <K, V> Map<K, V> readMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMap.class, name)) {
return readImmutableSortedMapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableBiMap.class, name)) {
return readImmutableBiMapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableMap.class, name)) {
return readImmutableMapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedMap.class, name)) {
return readSortedMapInternal(p, name);
} else if (ReflectionUtils.isAssignableFrom(BiMap.class, name)) {
return readBiMapInternal(p, name);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Map<K, V> outVal = (Map<K, V>) ReflectionUtils.newInstance(name);
return addToMap(p, outVal, n);
}
}
public static <K, V> SortedMap<K, V> readSortedMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMap.class, name)) {
return readImmutableSortedMapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(PatriciaTrie.class, name)) {
@SuppressWarnings("unchecked")
SortedMap<K, V> sortedMap = (SortedMap<K, V>) readPatriciaTrieInternal(p);
return sortedMap;
} else {
return readSortedMapInternal(p, name);
}
}
private static <K, V> SortedMap<K, V> readSortedMapInternal(Parcel p, String name) {
int n = p.readInt();
Comparator<? super K> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
SortedMap<K, V> outVal = (SortedMap<K, V>) ReflectionUtils.newInstance(name);
return addToMap(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
SortedMap<K, V> outVal = (SortedMap<K, V>) ReflectionUtils.newInstance(name, COMPARATOR_ARG, c);
return addToMap(p, outVal, n);
}
}
public static <K, V> NavigableMap<K, V> readNavigableMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMap.class, name)) {
return readImmutableSortedMapInternal(p);
} else {
int n = p.readInt();
Comparator<? super K> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
NavigableMap<K, V> outVal = (NavigableMap<K, V>) ReflectionUtils.newInstance(name);
return addToMap(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
NavigableMap<K, V> outVal = (NavigableMap<K, V>) ReflectionUtils.newInstance(name, COMPARATOR_ARG, c);
return addToMap(p, outVal, n);
}
}
}
public static <K, V> BiMap<K, V> readBiMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableBiMap.class, name)) {
return readImmutableBiMapInternal(p);
} else {
return readBiMapInternal(p, name);
}
}
private static <K, V> BiMap<K, V> readBiMapInternal(Parcel p, String name) {
int n = p.readInt();
@SuppressWarnings("unchecked")
BiMap<K, V> outVal = (BiMap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToMap(p, outVal, n);
}
// public static <K extends Enum<K>, V extends Enum<V>> EnumBiMap<K, V> readEnumBiMap(Parcel p) {
// if (p.readString().equals(NO_NAME)) {
// return null;
// } else {
// int n = p.readInt();
// EnumBiMap<K, V> outVal = EnumBiMap.create(???, ???);
//
// for (int i = 0; i < n; i++) {
// @SuppressWarnings("unchecked")
// K k = (K) readValue(p);
// @SuppressWarnings("unchecked")
// V v = (V) readValue(p);
// outVal.put(k, v);
// }
// return outVal;
// }
// }
//
// public static <K extends Enum<K>, V> EnumHashBiMap<K, V> readEnumBiMap(Parcel p) {
// if (p.readString().equals(NO_NAME)) {
// return null;
// } else {
// int n = p.readInt();
// EnumHashBiMap<K, V> outVal = EnumHashBiMap.create(???);
//
// for (int i = 0; i < n; i++) {
// @SuppressWarnings("unchecked")
// K k = (K) readValue(p);
// @SuppressWarnings("unchecked")
// V v = (V) readValue(p);
// outVal.put(k, v);
// }
// return outVal;
// }
// }
//
// public static <K extends Enum<K>, V> EnumMap<K, V> readEnumMap(Parcel p) {
// if (p.readString().equals(NO_NAME)) {
// return null;
// } else {
// int n = p.readInt();
// EnumMap<K, V> outVal = new EnumMap<K, V>();
//
// for (int i = 0; i < n; i++) {
// @SuppressWarnings("unchecked")
// K k = (K) readValue(p);
// @SuppressWarnings("unchecked")
// V v = (V) readValue(p);
// outVal.put(k, v);
// }
// return outVal;
// }
// }
public static <K, V> HashBiMap<K, V> readHashBiMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
HashBiMap<K, V> outVal = HashBiMap.create(n);
return addToMap(p, outVal, n);
}
}
public static <K, V> HashMap<K, V> readHashMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
HashMap<K, V> outVal = new HashMap<K, V>(n);
return addToMap(p, outVal, n);
}
}
public static <K, V> Hashtable<K, V> readHashtable(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Hashtable<K, V> outVal = new Hashtable<K, V>(n);
return addToMap(p, outVal, n);
}
}
public static <K, V> LinkedHashMap<K, V> readLinkedHashMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
LinkedHashMap<K, V> outVal = new LinkedHashMap<K, V>(n);
return addToMap(p, outVal, n);
}
}
public static <K, V> TreeMap<K, V> readTreeMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Comparator<? super K> c = readComparator(p);
TreeMap<K, V> outVal;
if (c == null) {
outVal = new TreeMap<K, V>();
} else {
outVal = new TreeMap<K, V>(c);
}
return addToMap(p, outVal, n);
}
}
private static <K, V, M extends Map<K, V>> M addToMap(Parcel p, M outVal, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
K k = (K) readValue(p);
@SuppressWarnings("unchecked")
V v = (V) readValue(p);
outVal.put(k, v);
}
return outVal;
}
public static <K, V> ImmutableMap<K, V> readImmutableMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMap.class, name)) {
return readImmutableSortedMapInternal(p);
} else {
return readImmutableMapInternal(p);
}
}
private static <K, V> ImmutableMap<K, V> readImmutableMapInternal(Parcel p) {
int n = p.readInt();
ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
addToImmutableMapBuilder(p, builder, n);
return builder.build();
}
public static <K, V> ImmutableSortedMap<K, V> readImmutableSortedMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableSortedMapInternal(p);
}
}
private static <K, V> ImmutableSortedMap<K, V> readImmutableSortedMapInternal(Parcel p) {
int n = p.readInt();
Comparator<K> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
ImmutableSortedMap.Builder<K, V> builder = (ImmutableSortedMap.Builder<K, V>) ImmutableSortedMap.naturalOrder();
addToImmutableMapBuilder(p, builder, n);
return builder.build();
} else {
ImmutableSortedMap.Builder<K, V> builder = ImmutableSortedMap.orderedBy(c);
addToImmutableMapBuilder(p, builder, n);
return builder.build();
}
}
public static <K, V> ImmutableBiMap<K, V> readImmutableBiMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableBiMapInternal(p);
}
}
private static <K, V> ImmutableBiMap<K, V> readImmutableBiMapInternal(Parcel p) {
int n = p.readInt();
ImmutableBiMap.Builder<K, V> builder = ImmutableBiMap.builder();
addToImmutableMapBuilder(p, builder, n);
return builder.build();
}
private static <K, V> void addToImmutableMapBuilder(Parcel p, ImmutableMap.Builder<K, V> builder, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
K k = (K) readValue(p);
@SuppressWarnings("unchecked")
V v = (V) readValue(p);
builder.put(k, v);
}
}
public static <K, V> Multimap<K, V> readMultimap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableListMultimap.class, name)) {
return readImmutableListMultimapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableSetMultimap.class, name)) {
return readImmutableSetMultimapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(TreeMultimap.class, name)) {
return readTreeMultimapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedSetMultimap.class, name)) {
return readSortedSetMultimapInternal(p, name);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Multimap<K, V> outVal = (Multimap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> ListMultimap<K, V> readListMultimap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableListMultimap.class, name)) {
return readImmutableListMultimapInternal(p);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
ListMultimap<K, V> outVal = (ListMultimap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> ArrayListMultimap<K, V> readArrayListMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
ArrayListMultimap<K, V> outVal = ArrayListMultimap.create(n, 3);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> LinkedListMultimap<K, V> readLinkedListMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
LinkedListMultimap<K, V> outVal = LinkedListMultimap.create(n);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> SetMultimap<K, V> readSetMultimap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSetMultimap.class, name)) {
return readImmutableSetMultimapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(TreeMultimap.class, name)) {
return readTreeMultimapInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedSetMultimap.class, name)) {
return readSortedSetMultimapInternal(p, name);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
SetMultimap<K, V> outVal = (SetMultimap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> HashMultimap<K, V> readHashMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
HashMultimap<K, V> outVal = HashMultimap.create(n, 2);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> LinkedHashMultimap<K, V> readLinkedHashMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
LinkedHashMultimap<K, V> outVal = LinkedHashMultimap.create(n, 2);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> SortedSetMultimap<K, V> readSortedSetMultimap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(TreeMultimap.class, name)) {
return readTreeMultimapInternal(p);
} else {
return readSortedSetMultimapInternal(p, name);
}
}
private static <K, V> SortedSetMultimap<K, V> readSortedSetMultimapInternal(Parcel p, String name) {
int n = p.readInt();
Comparator<? super V> valC = readComparator(p);
if (valC == null) {
@SuppressWarnings("unchecked")
SortedSetMultimap<K, V> outVal = (SortedSetMultimap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToMultimap(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
SortedSetMultimap<K, V> outVal = (SortedSetMultimap<K, V>) ReflectionUtils.singletonInstance(name, CREATE, valC);
return addToMultimap(p, outVal, n);
}
}
public static <K, V> TreeMultimap<K, V> readTreeMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readTreeMultimapInternal(p);
}
}
private static <K, V> TreeMultimap<K, V> readTreeMultimapInternal(Parcel p) {
int n = p.readInt();
Comparator<? super K> keyC = readComparator(p);
Comparator<? super V> valC = readComparator(p);
if (keyC == null && valC == null) {
@SuppressWarnings("unchecked")
TreeMultimap<K, V> outVal = (TreeMultimap<K, V>) TreeMultimap.create();
return addToMultimap(p, outVal, n);
} else if (keyC == null && valC != null) {
@SuppressWarnings("unchecked")
TreeMultimap<K, V> outVal = (TreeMultimap<K, V>) TreeMultimap.create(Ordering.natural(), valC);
return addToMultimap(p, outVal, n);
} else if (keyC != null && valC == null) {
@SuppressWarnings("unchecked")
TreeMultimap<K, V> outVal = (TreeMultimap<K, V>) TreeMultimap.create(keyC, Ordering.natural());
return addToMultimap(p, outVal, n);
} else {
TreeMultimap<K, V> outVal = TreeMultimap.create(keyC, valC);
return addToMultimap(p, outVal, n);
}
}
private static <K, V, M extends Multimap<K, V>> M addToMultimap(Parcel p, M outVal, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
K k = (K) readValue(p);
int q = p.readInt();
for (int j = 0; j < q; j++) {
@SuppressWarnings("unchecked")
V v = (V) readValue(p);
outVal.put(k, v);
}
}
return outVal;
}
public static <K, V> ImmutableListMultimap<K, V> readImmutableListMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableListMultimapInternal(p);
}
}
private static <K, V> ImmutableListMultimap<K, V> readImmutableListMultimapInternal(Parcel p) {
int n = p.readInt();
ImmutableListMultimap.Builder<K, V> builder = ImmutableListMultimap.builder();
addToImmutableMultimapBuilder(p, builder, n);
return builder.build();
}
public static <K, V> ImmutableSetMultimap<K, V> readImmutableSetMultimap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableSetMultimapInternal(p);
}
}
private static <K, V> ImmutableSetMultimap<K, V> readImmutableSetMultimapInternal(Parcel p) {
int n = p.readInt();
ImmutableSetMultimap.Builder<K, V> builder = ImmutableSetMultimap.builder();
addToImmutableMultimapBuilder(p, builder, n);
return builder.build();
}
private static <K, V> void addToImmutableMultimapBuilder(Parcel p, ImmutableMultimap.Builder<K, V> builder, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
K k = (K) readValue(p);
int q = p.readInt();
for (int j = 0; j < q; j++) {
@SuppressWarnings("unchecked")
V v = (V) readValue(p);
builder.put(k, v);
}
}
}
public static <E> Multiset<E> readMultiset(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMultiset.class, name)) {
return readImmutableSortedMultisetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableMultiset.class, name)) {
return readImmutableMultisetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedMultiset.class, name)) {
return readSortedMultisetInternal(p, name);
} else {
return readMultisetInternal(p, name);
}
}
private static <E> Multiset<E> readMultisetInternal(Parcel p, String name) {
int n = p.readInt();
@SuppressWarnings("unchecked")
Multiset<E> outVal = (Multiset<E>) ReflectionUtils.singletonInstance(name, CREATE);
return addToCollection(p, outVal, n);
}
// public static <E extends Enum<E>> EnumMultiset<E> readEnumMultiset(Parcel p) {
// if (p.readString().equals(NO_NAME)) {
// return null;
// } else {
// int n = p.readInt();
// EnumMultiset<E> outVal = EnumMultiset.create(???);
// return addToCollection(p, outVal, n);
// }
// }
public static <E> HashMultiset<E> readHashMultiset(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
HashMultiset<E> outVal = HashMultiset.create(n);
return addToCollection(p, outVal, n);
}
}
public static <E> LinkedHashMultiset<E> readLinkedHashMultiset(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
LinkedHashMultiset<E> outVal = LinkedHashMultiset.create(n);
return addToCollection(p, outVal, n);
}
}
public static <E> SortedMultiset<E> readSortedMultiset(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMultiset.class, name)) {
return readImmutableSortedMultisetInternal(p);
} else {
return readSortedMultisetInternal(p, name);
}
}
private static <E> SortedMultiset<E> readSortedMultisetInternal(Parcel p, String name) {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
SortedMultiset<E> outVal = (SortedMultiset<E>) ReflectionUtils.singletonInstance(name, CREATE);
return addToCollection(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
SortedMultiset<E> outVal = (SortedMultiset<E>) ReflectionUtils.singletonInstance(name, CREATE, c);
return addToCollection(p, outVal, n);
}
}
public static <E> TreeMultiset<E> readTreeMultiset(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
TreeMultiset<E> outVal = (TreeMultiset<E>) TreeMultiset.create();
return addToCollection(p, outVal, n);
} else {
TreeMultiset<E> outVal = TreeMultiset.create(c);
return addToCollection(p, outVal, n);
}
}
}
public static <E> ImmutableMultiset<E> readImmutableMultiset(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMultiset.class, name)) {
return readImmutableSortedMultisetInternal(p);
} else {
return readImmutableMultisetInternal(p);
}
}
private static <E> ImmutableMultiset<E> readImmutableMultisetInternal(Parcel p) {
int n = p.readInt();
ImmutableMultiset.Builder<E> builder = ImmutableMultiset.builder();
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
public static <E> ImmutableSortedMultiset<E> readImmutableSortedMultiset(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableSortedMultisetInternal(p);
}
}
private static <E> ImmutableSortedMultiset<E> readImmutableSortedMultisetInternal(Parcel p) {
int n = p.readInt();
Comparator<E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
ImmutableSortedMultiset.Builder<E> builder = (ImmutableSortedMultiset.Builder<E>) ImmutableSortedMultiset.naturalOrder();
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
} else {
ImmutableSortedMultiset.Builder<E> builder = ImmutableSortedMultiset.orderedBy(c);
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
}
public static <T> Optional<T> readOptional(Parcel p) {
int s = p.readInt();
if (s == -1) {
return null;
} else if (s == 0) {
return Optional.absent();
} else {
@SuppressWarnings("unchecked")
T thing = (T) readValue(p);
return Optional.of(thing);
}
}
public static <E> Queue<E> readQueue(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(PriorityQueue.class, name)) {
return readPriorityQueueInternal(p);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Queue<E> outVal = (Queue<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
}
}
public static <E> Deque<E> readDeque(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Deque<E> outVal = (Deque<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
}
}
public static <E> ArrayDeque<E> readArrayDeque(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
ArrayDeque<E> outVal = new ArrayDeque<E>(n);
return addToCollection(p, outVal, n);
}
}
public static <E> PriorityQueue<E> readPriorityQueue(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readPriorityQueueInternal(p);
}
}
private static <E> PriorityQueue<E> readPriorityQueueInternal(Parcel p) {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
PriorityQueue<E> outVal;
if (c == null) {
outVal = new PriorityQueue<E>(n);
} else {
outVal = new PriorityQueue<E>(n, c);
}
return addToCollection(p, outVal, n);
}
public static <C extends Comparable<?>> Range<C> readRange(Parcel p) {
int s = p.readInt();
if (s == -1) {
return null;
} else if (s == 0) {
return Range.all();
} else if (s == 1) {
BoundType lowerType = readBoolean(p) ? BoundType.CLOSED : BoundType.OPEN;
@SuppressWarnings("unchecked")
C lowerVal = (C) readValue(p);
return Range.downTo(lowerVal, lowerType);
} else if (s == 2) {
BoundType upperType = readBoolean(p) ? BoundType.CLOSED : BoundType.OPEN;
@SuppressWarnings("unchecked")
C upperVal = (C) readValue(p);
return Range.upTo(upperVal, upperType);
} else {
BoundType lowerType = readBoolean(p) ? BoundType.CLOSED : BoundType.OPEN;
@SuppressWarnings("unchecked")
C lowerVal = (C) readValue(p);
BoundType upperType = readBoolean(p) ? BoundType.CLOSED : BoundType.OPEN;
@SuppressWarnings("unchecked")
C upperVal = (C) readValue(p);
return Range.range(lowerVal, lowerType, upperVal, upperType);
}
// } else {
// BoundType lowerType = readEnum(p);
// @SuppressWarnings("unchecked")
// C lowerVal = (C) readValue(p);
//
// BoundType upperType = readEnum(p);
// @SuppressWarnings("unchecked")
// C upperVal = (C) readValue(p);
//
// if (lowerVal != null && upperVal != null) {
// return Range.range(lowerVal, lowerType, upperVal, upperType);
// } else if (lowerVal != null) {
// return Range.downTo(lowerVal, lowerType);
// } else if (upperVal != null) {
// return Range.upTo(upperVal, upperType);
// } else {
// return Range.all();
// }
// }
}
public static <K extends Comparable<?>, V> RangeMap<K, V> readRangeMap(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableRangeMap.class, name)) {
return readImmutableRangeMapInternal(p);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
RangeMap<K, V> outVal = (RangeMap<K, V>) ReflectionUtils.singletonInstance(name, CREATE);
return addToRangeMap(p, outVal, n);
}
}
public static <K extends Comparable<?>, V> TreeRangeMap<K, V> readTreeRangeMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
TreeRangeMap<K, V> outVal = TreeRangeMap.create();
return addToRangeMap(p, outVal, n);
}
}
public static <K extends Comparable<?>, V> ImmutableRangeMap<K, V> readImmutableRangeMap(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableRangeMap(p);
}
}
private static <K extends Comparable<?>, V> ImmutableRangeMap<K, V> readImmutableRangeMapInternal(Parcel p) {
int n = p.readInt();
ImmutableRangeMap.Builder<K, V> builder = ImmutableRangeMap.builder();
for (int i = 0; i < n; i++) {
Range<K> range = readRange(p);
@SuppressWarnings("unchecked")
V value = (V) readValue(p);
builder.put(range, value);
}
return builder.build();
}
private static <K extends Comparable<?>, V, RM extends RangeMap<K, V>> RM addToRangeMap(Parcel p, RM outVal, int size) {
for (int i = 0; i < size; i++) {
Range<K> range = readRange(p);
@SuppressWarnings("unchecked")
V value = (V) readValue(p);
outVal.put(range, value);
}
return outVal;
}
public static <E> Set<E> readSet(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableSet.class, name)) {
return readImmutableSetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedSet.class, name)) {
return readSortedSetInternal(p, name);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Set<E> outVal = (Set<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
}
}
// private static <E extends Enum<E>> EnumSet<E> readEnumSet(Parcel p) {
// if (p.readString().equals(NO_NAME)) {
// return null;
// } else {
// int n = p.readInt();
// EnumSet<E> outVal = new EnumSet<E>();
// return addToCollection(p, outVal, n);
// }
// }
public static <E> HashSet<E> readHashSet(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
HashSet<E> outVal = new HashSet<E>();
return addToCollection(p, outVal, n);
}
}
public static <E> ImmutableSet<E> readImmutableSet(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else {
return readImmutableSetInternal(p);
}
}
private static <E> ImmutableSet<E> readImmutableSetInternal(Parcel p) {
int n = p.readInt();
ImmutableSet.Builder<E> builder = ImmutableSet.builder();
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
public static <E> NavigableSet<E> readNavigableSet(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
NavigableSet<E> outVal = (NavigableSet<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
NavigableSet<E> outVal = (NavigableSet<E>) ReflectionUtils.newInstance(name, COMPARATOR_ARG, c);
return addToCollection(p, outVal, n);
}
}
}
public static <E> TreeSet<E> readTreeSet(Parcel p) {
if (p.readString() == null) {
return null;
} else {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
TreeSet<E> outVal;
if (c == null) {
outVal = new TreeSet<E>();
} else {
outVal = new TreeSet<E>(c);
}
return addToCollection(p, outVal, n);
}
}
public static <E> SortedSet<E> readSortedSet(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else {
return readSortedSetInternal(p, name);
}
}
private static <E> SortedSet<E> readSortedSetInternal(Parcel p, String name) {
int n = p.readInt();
Comparator<? super E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
SortedSet<E> outVal = (SortedSet<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
} else {
@SuppressWarnings("unchecked")
SortedSet<E> outVal = (SortedSet<E>) ReflectionUtils.newInstance(name, COMPARATOR_ARG, c);
return addToCollection(p, outVal, n);
}
}
public static <E> ImmutableSortedSet<E> readImmutableSortedSet(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readImmutableSortedSetInternal(p);
}
}
private static <E> ImmutableSortedSet<E> readImmutableSortedSetInternal(Parcel p) {
int n = p.readInt();
Comparator<E> c = readComparator(p);
if (c == null) {
@SuppressWarnings("unchecked")
ImmutableSortedSet.Builder<E> builder = (ImmutableSortedSet.Builder<E>) ImmutableSortedSet.naturalOrder();
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
} else {
ImmutableSortedSet.Builder<E> builder = ImmutableSortedSet.orderedBy(c);
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
}
public static <V> PatriciaTrie<V> readPatriciaTrie(Parcel p) {
if (p.readString() == null) {
return null;
} else {
return readPatriciaTrieInternal(p);
}
}
private static <V> PatriciaTrie<V> readPatriciaTrieInternal(Parcel p) {
int n = p.readInt();
PatriciaTrie<V> outVal = new PatriciaTrie<V>();
return addToMap(p, outVal, n);
}
public static <E> Collection<E> readCollection(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMultiset.class, name)) {
return readImmutableSortedMultisetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableCollection.class, name)) {
return readImmutableCollectionInternal(p, name);
} else if (ReflectionUtils.isAssignableFrom(PriorityQueue.class, name)) {
return readPriorityQueueInternal(p);
} else if (ReflectionUtils.isAssignableFrom(SortedMultiset.class, name)) {
return readSortedMultisetInternal(p, name);
} else if (ReflectionUtils.isAssignableFrom(SortedSet.class, name)) {
return readSortedSetInternal(p, name);
} else if (ReflectionUtils.isAssignableFrom(Multiset.class, name)) {
return readMultisetInternal(p, name);
} else {
int n = p.readInt();
@SuppressWarnings("unchecked")
Collection<E> outVal = (Collection<E>) ReflectionUtils.newInstance(name);
return addToCollection(p, outVal, n);
}
}
public static <E> ImmutableCollection<E> readImmutableCollection(Parcel p) {
String name = p.readString();
if (name == null) {
return null;
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedMultiset.class, name)) {
return readImmutableSortedMultisetInternal(p);
} else if (ReflectionUtils.isAssignableFrom(ImmutableSortedSet.class, name)) {
return readImmutableSortedSetInternal(p);
} else {
return readImmutableCollectionInternal(p, name);
}
}
private static <E> ImmutableCollection<E> readImmutableCollectionInternal(Parcel p, String name) {
int n = p.readInt();
@SuppressWarnings("unchecked")
ImmutableCollection.Builder<E> builder = (ImmutableCollection.Builder<E>) ReflectionUtils.singletonInstance(name, BUILDER);
addToImmutableCollectionBuilder(p, builder, n);
return builder.build();
}
private static <E, C extends Collection<E>> C addToCollection(Parcel p, C outVal, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
E elem = (E) readValue(p);
outVal.add(elem);
}
return outVal;
}
private static <E> void addToImmutableCollectionBuilder(Parcel p, ImmutableCollection.Builder<E> builder, int size) {
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
E elem = (E) readValue(p);
builder.add(elem);
}
}
private static <T> Comparator<T> readComparator(Parcel p) {
int s = p.readInt();
if (s == -1) {
return null;
} else if (s == 0) {
@SuppressWarnings("unchecked")
Comparator<T> c = (Comparator<T>) p.readParcelable(ParcelUtils.class.getClassLoader());
return c;
} else {
@SuppressWarnings("unchecked")
Comparator<T> c = (Comparator<T>) p.readSerializable();
return c;
}
}
public static final Object readValue(Parcel p) {
int type = p.readInt();
switch (type) {
case VAL_BOOLEAN:
return readBoolean(p);
case VAL_ENUM:
return readEnum(p);
case VAL_LIST2:
return readList(p);
case VAL_PATRICIATRIE:
return readPatriciaTrie(p);
case VAL_SORTEDMAP:
return readSortedMap(p);
case VAL_MAP2:
return readMap(p);
case VAL_TREEMULTIMAP:
return readTreeMultimap(p);
case VAL_SORTEDSETMULTIMAP:
return readSortedSetMultimap(p);
case VAL_MULTIMAP:
return readMultimap(p);
case VAL_SORTEDMULTISET:
return readSortedMultiset(p);
case VAL_MULTISET:
return readMultiset(p);
case VAL_OPTIONAL:
return readOptional(p);
case VAL_PRIORITYQUEUE:
return readPriorityQueue(p);
case VAL_QUEUE:
return readQueue(p);
case VAL_RANGE:
return readRange(p);
case VAL_RANGEMAP:
return readRangeMap(p);
case VAL_SORTEDSET:
return readSortedSet(p);
case VAL_SET:
return readSet(p);
case VAL_COLLECTION:
return readCollection(p);
default:
/* For some bizarre reason, you have to pass in a ClassLoader from a class
* in the app itself. Using a ClassLoader from a regular Java class won't
* work. I have absolutely no idea why.
*/
return p.readValue(ParcelUtils.class.getClassLoader());
}
}
public static void writeBoolean(Parcel p, boolean b) {
p.writeInt(b ? 1 : 0);
}
public static <E extends Enum<?>> void writeEnum(Parcel p, E enumVal) {
if (enumVal == null) {
p.writeString(null);
} else {
p.writeString(enumVal.getDeclaringClass().getName());
p.writeString(enumVal.name());
}
}
// public static <K extends Enum<K>, V extends Enum<V>> void writeEnumBiMap(Parcel p, EnumBiMap<K, V> enumBiMap, Class<K> keyCls, Class<V> valueCls) {
//
// }
//
// public static <K extends Enum<K>, V> void writeEnumHashBiMap(Parcel p, EnumHashBiMap<K, V> enumHashBiMap, Class<K> cls) {
//
// }
//
// public static <K extends Enum<K>, V> void writeEnumMap(Parcel p, EnumMap<K, V> enumMap, Class<K> cls) {
//
// }
//
// public static <E extends Enum<E>> void writeEnumMultiset(Parcel p, EnumMultiset<E> enumMultiset, Class<E> cls) {
//
// }
//
// public static <E extends Enum<E>> void writeEnumSet(Parcel p, EnumSet<E> enumSet, Class<E> cls) {
//
// }
public static <K, V> void writeMap(Parcel p, Map<K, V> map) {
if (map instanceof PatriciaTrie) {
writeMap(p, map, YesNoMaybe.NO, null);
} else {
writeMap(p, map, YesNoMaybe.MAYBE, null);
}
}
private static <K, V> void writeMap(Parcel p, Map<K, V> map, YesNoMaybe hasComparator, Comparator<? super K> comparator) {
if (map == null) {
p.writeString(null);
} else {
p.writeString(map.getClass().getName());
p.writeInt(map.size());
switch (hasComparator) {
case YES:
writeComparator(p, comparator);
break;
case MAYBE:
if (map instanceof SortedMap) { // Ensure that PatriciaTries never reach this point
SortedSet<?> sortedSet = (SortedSet<?>) map;
Comparator<?> c = sortedSet.comparator();
writeComparator(p, c);
}
break;
case NO:
break;
}
for (Map.Entry<K, V> entry : map.entrySet()) {
writeValue(p, entry.getKey());
writeValue(p, entry.getValue());
}
}
}
public static <K, V> void writeMultimap(Parcel p, Multimap<K, V> multimap) {
writeMultimap(p, multimap, YesNoMaybe.MAYBE, null, YesNoMaybe.MAYBE, null);
}
public static <K, V> void writeMultimap(Parcel p, Multimap<K, V> multimap,
YesNoMaybe hasKeyComparator, Comparator<? super K> keyComparator,
YesNoMaybe hasValueComparator, Comparator<? super V> valueComparator) {
if (multimap == null) {
p.writeString(null);
} else {
p.writeString(multimap.getClass().getName());
p.writeInt(multimap.size());
switch (hasKeyComparator) {
case YES:
writeComparator(p, keyComparator);
break;
case MAYBE:
if (multimap instanceof TreeMultimap) {
TreeMultimap<?, ?> treeMultimap = (TreeMultimap<?, ?>) multimap;
Comparator<?> keyC = treeMultimap.keyComparator();
writeComparator(p, keyC);
}
break;
case NO:
break;
}
switch (hasValueComparator) {
case YES:
writeComparator(p, valueComparator);
break;
case MAYBE:
if (multimap instanceof SortedSetMultimap) {
SortedSetMultimap<?, ?> sortedSetMultimap = (SortedSetMultimap<?, ?>) multimap;
Comparator<?> valueC = sortedSetMultimap.valueComparator();
writeComparator(p, valueC);
}
break;
case NO:
break;
}
for (Map.Entry<K, Collection<V>> entry : multimap.asMap().entrySet()) {
writeValue(p, entry.getKey());
p.writeInt(entry.getValue().size());
for (V v : entry.getValue()) {
writeValue(p, v);
}
}
}
}
public static <T> void writeOptional(Parcel p, Optional<T> opt) {
if (opt == null) {
p.writeInt(-1);
} else if (opt.isPresent()) {
p.writeInt(1);
writeValue(p, opt.get());
} else {
p.writeInt(0);
}
}
public static <V> void writePatriciaTrie(Parcel p, PatriciaTrie<V> patriciaTrie) {
writeMap(p, patriciaTrie, YesNoMaybe.NO, null);
}
public static <E> void writePriorityQueue(Parcel p, PriorityQueue<E> priorityQueue) {
writeCollection(p, priorityQueue, YesNoMaybe.YES, priorityQueue.comparator());
}
public static <C extends Comparable<?>> void writeRange(Parcel p, Range<C> range) {
if (range == null) {
p.writeInt(-1);
} else {
if (!range.hasLowerBound() && !range.hasUpperBound()) {
p.writeInt(0);
} else if (range.hasLowerBound() && !range.hasUpperBound()) {
p.writeInt(1);
writeRangeEndpoint(p, range.lowerBoundType(), range.lowerEndpoint());
} else if (!range.hasLowerBound() && range.hasUpperBound()) {
p.writeInt(2);
writeRangeEndpoint(p, range.upperBoundType(), range.upperEndpoint());
} else {
p.writeInt(3);
writeRangeEndpoint(p, range.lowerBoundType(), range.lowerEndpoint());
writeRangeEndpoint(p, range.upperBoundType(), range.upperEndpoint());
}
// p.writeInt(1);
// if (range.hasLowerBound()) {
// writeEnum(p, range.lowerBoundType());
// writeValue(p, range.lowerEndpoint());
// } else {
// writeEnum(p, null);
// p.writeValue(null);
// }
//
// if (range.hasUpperBound()) {
// writeEnum(p, range.upperBoundType());
// writeValue(p, range.upperEndpoint());
// } else {
// writeEnum(p, null);
// p.writeValue(null);
// }
}
}
private static <C extends Comparable<?>> void writeRangeEndpoint(Parcel p, BoundType boundType, C endpoint) {
switch (boundType) {
case OPEN:
writeBoolean(p, false);
break;
case CLOSED:
writeBoolean(p, true);
break;
}
writeValue(p, endpoint);
}
public static <K extends Comparable<?>, V> void writeRangeMap(Parcel p, RangeMap<K, V> rangeMap) {
if (rangeMap == null) {
p.writeString(null);
} else {
p.writeString(rangeMap.getClass().getName());
p.writeInt(rangeMap.asMapOfRanges().size());
for (Map.Entry<Range<K>, V> entry : rangeMap.asMapOfRanges().entrySet()) {
writeRange(p, entry.getKey());
writeValue(p, entry.getValue());
}
}
}
public static <K, V> void writeSortedMap(Parcel p, SortedMap<K, V> sortedMap) {
if (sortedMap instanceof PatriciaTrie) {
writeMap(p, sortedMap, YesNoMaybe.NO, null);
} else {
writeMap(p, sortedMap, YesNoMaybe.YES, sortedMap.comparator());
}
}
public static <E> void writeSortedMultiset(Parcel p, SortedMultiset<E> sortedMultiset) {
writeCollection(p, sortedMultiset, YesNoMaybe.YES, sortedMultiset.comparator());
}
public static <E> void writeSortedSet(Parcel p, SortedSet<E> sortedSet) {
writeCollection(p, sortedSet, YesNoMaybe.YES, sortedSet.comparator());
}
public static <K, V> void writeSortedSetMultimap(Parcel p, SortedSetMultimap<K, V> sortedSetMultimap) {
writeMultimap(p, sortedSetMultimap, YesNoMaybe.MAYBE, null, YesNoMaybe.YES, sortedSetMultimap.valueComparator());
}
public static <K, V> void writeTreeMultimap(Parcel p, TreeMultimap<K, V> treeMultimap) {
writeMultimap(p, treeMultimap, YesNoMaybe.YES, treeMultimap.keyComparator(), YesNoMaybe.YES, treeMultimap.valueComparator());
}
public static <E> void writeCollection(Parcel p, Collection<E> collection) {
writeCollection(p, collection, YesNoMaybe.MAYBE, null);
}
private static <T> void writeComparator(Parcel p, Comparator<T> comparator) {
if (comparator == null || Ordering.natural().equals(comparator)) {
p.writeInt(-1);
} else if (comparator instanceof Parcelable) {
p.writeInt(0);
p.writeParcelable((Parcelable) comparator, 0);
} else if (comparator instanceof Serializable) {
p.writeInt(1);
p.writeSerializable((Serializable) comparator);
} else {
p.writeInt(-1);
}
}
private static <E> void writeCollection(Parcel p, Collection<E> collection, YesNoMaybe hasComparator, Comparator<? super E> comparator) {
if (collection == null) {
p.writeString(null);
} else {
p.writeString(collection.getClass().getName());
p.writeInt(collection.size());
switch (hasComparator) {
case YES:
writeComparator(p, comparator);
break;
case MAYBE:
Comparator<?> c = null;
if (collection instanceof PriorityQueue) {
PriorityQueue<?> priorityQueue = (PriorityQueue<?>) collection;
c = priorityQueue.comparator();
} else if (collection instanceof SortedMultiset) {
SortedMultiset<?> sortedMultiset = (SortedMultiset<?>) collection;
c = sortedMultiset.comparator();
} else if (collection instanceof SortedSet) {
SortedSet<?> sortedSet = (SortedSet<?>) collection;
c = sortedSet.comparator();
}
if (c != null) {
writeComparator(p, c);
}
break;
case NO:
break;
}
for (E elem : collection) {
writeValue(p, elem);
}
}
}
public static void writeValue(Parcel p, Object v) {
if (v instanceof Boolean) {
p.writeInt(VAL_BOOLEAN);
writeBoolean(p, (Boolean) v);
} else if (v.getClass().isEnum()) {
p.writeInt(VAL_BOOLEAN);
@SuppressWarnings("unchecked")
Enum<? extends Enum<?>> e = (Enum<? extends Enum<?>>) v;
writeEnum(p, e);
} else if (v instanceof List) {
p.writeInt(VAL_LIST2);
writeCollection(p, (List<?>) v);
} else if (v instanceof PatriciaTrie) {
p.writeInt(VAL_PATRICIATRIE);
writePatriciaTrie(p, (PatriciaTrie<?>) v);
} else if (v instanceof SortedMap) {
p.writeInt(VAL_SORTEDMAP);
writeSortedMap(p, (SortedMap<?, ?>) v);
} else if (v instanceof Map) {
p.writeInt(VAL_MAP2);
writeMap(p, (Map<?, ?>) v);
} else if (v instanceof TreeMultimap) {
p.writeInt(VAL_TREEMULTIMAP);
writeTreeMultimap(p, (TreeMultimap<?, ?>) v);
} else if (v instanceof SortedSetMultimap) {
p.writeInt(VAL_SORTEDSETMULTIMAP);
writeSortedSetMultimap(p, (SortedSetMultimap<?, ?>) v);
} else if (v instanceof Multimap) {
p.writeInt(VAL_MULTIMAP);
writeMultimap(p, (Multimap<?, ?>) v);
} else if (v instanceof SortedMultiset) {
p.writeInt(VAL_SORTEDMULTISET);
writeSortedMultiset(p, (SortedMultiset<?>) v);
} else if (v instanceof Multiset) {
p.writeInt(VAL_MULTISET);
writeCollection(p, (Multiset<?>) v);
} else if (v instanceof Optional) {
p.writeInt(VAL_OPTIONAL);
writeOptional(p, (Optional<?>) v);
} else if (v instanceof PriorityQueue) {
p.writeInt(VAL_PRIORITYQUEUE);
writePriorityQueue(p, (PriorityQueue<?>) v);
} else if (v instanceof Queue) {
p.writeInt(VAL_QUEUE);
writeCollection(p, (Queue<?>) v);
} else if (v instanceof Range) {
p.writeInt(VAL_RANGE);
@SuppressWarnings("unchecked")
Range<? extends Comparable<?>> range = (Range<? extends Comparable<?>>) v;
writeRange(p, range);
} else if (v instanceof RangeMap) {
p.writeInt(VAL_RANGEMAP);
@SuppressWarnings("unchecked")
RangeMap<? extends Comparable<?>, ?> rangeMap = (RangeMap<? extends Comparable<?>, ?>) v;
writeRangeMap(p, rangeMap);
} else if (v instanceof SortedSet) {
p.writeInt(VAL_SORTEDSET);
writeSortedSet(p, (SortedSet<?>) v);
} else if (v instanceof Set) {
p.writeInt(VAL_SET);
writeCollection(p, (Set<?>) v);
} else if (v instanceof Collection) {
p.writeInt(VAL_COLLECTION);
writeCollection(p, (Collection<?>) v);
} else { // Delegate to default writeValue()
p.writeInt(-2);
p.writeValue(v);
}
}
private static enum YesNoMaybe { YES, MAYBE, NO }
}